Amazon Linuxのcloud-initの動きについて調べてみた
はじめに
昨日Amazon Linuxのcloud-init Tips集という記事を書きましたが、他にも色々気になることがあって調べてみましたので、記事にしてみます。
調べてみたこと
実行タイミング
まず、cloud-initがいつ実行されるのかを調べてみました。Amazon Linux AMIでLaunchしたEC2のランレベルを確認すると、
$ runlevel N 3
なので、/etc/rc3.d/配下を確認してみます。
$ ls -alF /etc/rc3.d/ | grep cloud lrwxrwxrwx 1 root root 26 8月 5 10:58 S50cloud-init-local -> ../init.d/cloud-init-local* lrwxrwxrwx 1 root root 20 8月 5 10:58 S51cloud-init -> ../init.d/cloud-init* lrwxrwxrwx 1 root root 22 8月 5 10:58 S52cloud-config -> ../init.d/cloud-config* lrwxrwxrwx 1 root root 21 6月 12 01:51 S98cloud-final -> ../init.d/cloud-final*
このように、cloud-initの起動スクリプトは4つのファイルに分かれていました。通常sshやhttpdなどのサービスの起動スクリプトはS52よりも後でS98より先にあります。
lrwxrwxrwx 1 root root 14 7月 22 17:24 S55sshd -> ../init.d/sshd* lrwxrwxrwx 1 root root 17 6月 12 01:53 S57ntpdate -> ../init.d/ntpdate* lrwxrwxrwx 1 root root 14 6月 12 01:53 S58ntpd -> ../init.d/ntpd* lrwxrwxrwx 1 root root 18 6月 12 01:51 S80sendmail -> ../init.d/sendmail* lrwxrwxrwx 1 root root 15 6月 12 01:51 S90crond -> ../init.d/crond* lrwxrwxrwx 1 root root 13 6月 12 01:52 S95atd -> ../init.d/atd*
このため実行順序としては
- cloud-init-local
- cloud-init
- cloud-config
- 各種サービスの起動
- cloud-final
となります。
それぞれの起動スクリプトがやっていること
この4つの起動スクリプトの内容を確認すると、以下のような違いがありました。
$ diff cloud-init-local cloud-init 70c70 < $cloud_init $CLOUDINITARGS init --local --- > $cloud_init $CLOUDINITARGS init $ diff cloud-init-local cloud-config 70c70 < $cloud_init $CLOUDINITARGS init --local --- > $cloud_init $CLOUDINITARGS modules --mode config $ diff cloud-init-local cloud-final 70c77 < $cloud_init $CLOUDINITARGS init --local --- > $cloud_init $CLOUDINITARGS modules --mode final
内容はほぼ同一で、$cloud_init(/usr/bin/cloud-init)への引数が違うだけでした。
この引数による違いは、cloud-initの設定ファイルである/etc/cloud/cloud.cfgと/etc/cloud/cloud.cfg.d/配下のスクリプトで確認できます。
$ cat /etc/cloud/cloud.cfg.d/00_defaults.cfg # ### DO NOT MODIFY THIS FILE! ### # This file will be replaced if cloud-init is upgraded. # Please put your modifications in other files under /etc/cloud/cloud.cfg.d/ # # Note that cloud-init uses flexible merge strategies for config options # http://cloudinit.readthedocs.org/en/latest/topics/merging.html # The top level settings are used as module # and system configuration. # A set of users which may be applied and/or used by various modules # when a 'default' entry is found it will reference the 'default_user' # from the distro configuration specified below users: - default ssh_pwauth: false # Example datasource config # datasource: # Ec2: # metadata_urls: [ 'blah.com' ] # timeout: 5 # (defaults to 50 seconds) # max_wait: 10 # (defaults to 120 seconds) locale_configfile: /etc/sysconfig/i18n mount_default_fields: [~, ~, 'auto', 'defaults,nofail', '0', '2'] resize_rootfs: noblock resize_rootfs_tmp: /dev ssh_deletekeys: true ssh_genkeytypes: [ 'rsa', 'dsa', 'ecdsa' ] syslog_fix_perms: ~ # The modules that run in the 'init' stage cloud_init_modules: - rsyslog - migrator - bootcmd - write-files - growpart - resizefs - set-hostname - update-hostname - update-etc-hosts - users-groups # The modules that run in the 'config' stage cloud_config_modules: - locale - ssh - set-passwords - mounts - yum-configure - yum-add-repo - package-update-upgrade-install - timezone - puppet - disable-ec2-metadata - runcmd # The modules that run in the 'final' stage cloud_final_modules: - scripts-per-once - scripts-per-boot - scripts-per-instance - scripts-user - ssh-authkey-fingerprints - keys-to-console - phone-home - final-message - power-state-change # System and/or distro specific settings # (not accessible to handlers/transforms) system_info: # This will affect which distro class gets used distro: amazon distro_short: amzn # Default user name + that default users groups (if added/used) default_user: name: ec2-user lock_passwd: true gecos: EC2 Default User groups: [ wheel ] sudo: [ "ALL=(ALL) NOPASSWD:ALL" ] shell: /bin/bash # Other config here will be given to the distro class and/or path classes paths: cloud_dir: /var/lib/cloud/ templates_dir: /etc/cloud/templates/ upstart_dir: /etc/init/ package_mirrors: - arches: [ i386, x86_64 ] search: regional: - repo.%(ec2_region)s.%(services_domain)s - repo.%(ec2_region)s.amazonaws.com ssh_svcname: sshd # vim:syntax=yaml expandtab
cloud-init-localとcloud-initではcloud_init_modulesが、cloud-configではcloud_config_modulesが、cloud-finalではcloud_final_modulesが、それぞれ実行されます。
例えばbootcmdやwrite-filesなどはcloud_init_modulesで実行されますので、cloud_config_modulesで実行されるyum-configureやruncmdなどより前に実行されることが分かりますね。
なお、ここに書いてある各モジュールは/usr/lib/python2.6/site-packages/cloudinit/configにあります。Pythonで書かれていますので、読むとどんな動きをしているのかがわかります。
User-Dataの読み込まれるタイミング
/usr/bin/cloud-initを読むと、以下のように記述されていました。
# Cloud-init 'init' stage is broken up into the following sub-stages # 1. Ensure that the init object fetches its config without errors # 2. Setup logging/output redirections with resultant config (if any) # 3. Initialize the cloud-init filesystem # 4. Check if we can stop early by looking for various files # 5. Fetch the datasource # 6. Connect to the current instance location + update the cache # 7. Consume the userdata (handlers get activated here) # 8. Construct the modules object # 9. Adjust any subsequent logging/output redirections using the modules # objects config as it may be different from init object # 10. Run the modules for the 'init' stage # 11. Done!
なので、cloud-initの段階でUser-Dataの内容(/var/lib/cloud/instance/user-data.txt)が読み込まれます。
まとめ
ということで、cloud-initの動きについて少し理解が深まりました。次は各moduleについて色々試してみたいと思います。